package com.qire.common.support.base;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;

import com.qire.common.support.DialogManage;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;

/**
 * 为了避免Splash广告不在对话框下面显示，把显示的对话框保存起来
 */
public class BaseDialog extends Dialog {

    /** 归属Activity */
    private BaseActivity ownerActivity;

    /** dialog优先级别，用于dialog的操作冲突中优先级别，比如显示级别高的会覆盖级别低的显示，而级别低的需要等待高级别显示完关闭才显示 */
    private int level = 0;

    public BaseDialog(@NonNull Context context) {
        this(context, 0);
    }

    public BaseDialog(@NonNull Context context, int themeResId) {
        super(context, themeResId);

        if(context instanceof BaseActivity) {
            ownerActivity = (BaseActivity) context;

            LifecycleObserverWrapper observerWrapper = new LifecycleObserverWrapper(this.ownerActivity);
            if(Lifecycle.State.CREATED.isAtLeast(this.ownerActivity.getLifecycle().getCurrentState())) {
                observerWrapper.activeStateChanged(true);
            }
            this.ownerActivity.getLifecycle().addObserver(observerWrapper);
        }
    }

    protected BaseDialog(@NonNull Context context, boolean cancelable, @Nullable DialogInterface.OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
    }

    public void postShow() {
        DialogManage.show(this);
    }

    @Override
    public void show() {
        if(ownerActivity == null)
            return;
        if(ownerActivity.isFinishing())
            return;
        if(ownerActivity.isDestroyed())
            return;

        super.show();
        DialogManage.add(this);
    }

    public void postDismiss() {
        DialogManage.dismiss(this);
    }

    @Override
    public void dismiss() {
        boolean isActive = ownerActivity != null && !ownerActivity.isFinishing() && !ownerActivity.isDestroyed();
        if(isShowing() && isActive) {
            super.dismiss();
        }
        DialogManage.remove(this);
    }

    /**
     * 比较与目标 dialog 的级别。
     * @param dialog 目标dialog
     * @return 如果目标级别高则返回大于 0 的级别差，如果目标级别低则返回小于 0 的级别差，如果相等则返回 0 。
     */
    public int compareLevel(BaseDialog dialog) {
        return dialog.level - this.level;
    }

    /**
     * 生命轴器观察者包装器
     */
    class LifecycleObserverWrapper implements LifecycleEventObserver {
        /** 所属 */
        @NonNull
        final LifecycleOwner mOwner;
        /** 激活状态 */
        boolean mActive;
        /** 最近一次失活时显示状态 */
        boolean lastShow = isShowing();

        LifecycleObserverWrapper(@NonNull LifecycleOwner owner) {
            mOwner = owner;
        }

        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }

        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED);
        }

        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            if (mOwner.getLifecycle().getCurrentState() == Lifecycle.State.DESTROYED) {
                detachObserver();
                activeStateChanged(false);
                dismiss();
                return;
            }
            activeStateChanged(shouldBeActive());
        }

        void activeStateChanged(boolean newActive) {
            // 激活状态未发生改变不做任何操作
            if (newActive == mActive) {
                return;
            }
            // 设置更新激活状态
            mActive = newActive;

            // 退到后台或页面未显示失活时
            if(!mActive) {
                // 保存当前的对话框显示状态
                lastShow = isShowing();
                // 如果事打开显示的状态则关闭对话框。
                if(lastShow) {
                    dismiss();
                }
            }

            // 页面重新激活时，检查退出前显示状态：如果是显示的则重新显示对话框，如果不是什么都不做。
            if(mActive && lastShow) {
                show();
            }

        }

        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }

}
